package com.wan.net.core.udp;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import io.netty.handler.codec.MessageToMessageCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.List;
/**
 * @author wwh
 * @date 2022/6/16 14:57
 */
public class UdpCodec extends MessageToMessageCodec<DatagramPacket, UdpPacket> {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Override
    protected void encode(ChannelHandlerContext context, UdpPacket pack, List<Object> list) throws Exception {
        Channel channel = context.channel();
        try {
            ByteBuf byteBuf = context.alloc().ioBuffer();
            pack.write(byteBuf);
            list.add(new DatagramPacket(byteBuf, new InetSocketAddress(pack.getHost(), pack.getPort())));
        } catch (Exception e) {
            log.error("UdpCodec encode exception异常!channel:{},pack:{}", channel, pack, e);
            throw e;
        } catch (Throwable t) {
            log.error("UdpCodec encode throwable异常!channel:{},pack:{}", channel, pack, t);
            throw t;
        }
    }

    @Override
    protected void decode(ChannelHandlerContext context, DatagramPacket datagramPacket, List<Object> out) throws Exception {
        Channel channel = context.channel();
        try {
            ByteBuf byteBuf = datagramPacket.content();
            byteBuf.markReaderIndex();
            UdpPacket packet = new UdpPacket();
            if(!packet.read(byteBuf)) return;
            InetSocketAddress sender = datagramPacket.sender();
            packet.setHost(sender.getHostString());
            packet.setPort(sender.getPort());
            out.add(packet);
        } catch (Exception e) {
            log.error("UdpCodec decode exception异常!{}", channel, e);
            throw e;
        } catch (Throwable e) {
            log.error("UdpCodec decode Throwable异常!{}", channel, e);
            throw e;
        }
    }
}
